/*
 * Copyright (c) 2021, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "ADC.h"
#include "No_Mcu_Ganv_Grayscale_Sensor_Config.h"
#include "Time.h"
#include "Uart.h"
#include "ti_msp_dl_config.h"

unsigned short Anolog[8] = {0};
// 1800,1800,1800,1800,1800,1800,1800,1800
//
unsigned short white[8] = {3105, 3152, 2239, 2756, 2944, 2257, 2791, 2376};
unsigned short black[8] = {1974, 1300, 709, 724, 742, 585, 412, 204};
unsigned short Normal[8];
unsigned char rx_buff[256] = {0};
void set_output_level(int chanel,int level);
/********************************************No_Mcu_Demo*******************************************/
/*****************芯片型号 MSPM0G3507 主频80Mhz
 * ***************************************************/
/*****************引脚 AD0:PB0 AD1:PB1 AD2:PB2
 * ***************************************************/
/*****************OUT
 * PA27*************************************************************************/
/********************************************No_Mcu_Demo*******************************************/

int main(void) {
  // 初始化
  No_MCU_Sensor sensor;
  unsigned char Digtal;
  SYSCFG_DL_init();

  // 初始化传感器，不带黑白值
  No_MCU_Ganv_Sensor_Init_Frist(&sensor);
  No_Mcu_Ganv_Sensor_Task_Without_tick(&sensor);
  Get_Anolog_Value(&sensor, Anolog);
  // 此时打印的ADC的值，可用通过这个ADC作为黑白值的校准
  // 也可以自己写按键逻辑完成一键校准功能

  sprintf((char *)rx_buff, "Anolog %d-%d-%d-%d-%d-%d-%d-%d\r\n", Anolog[0],
          Anolog[1], Anolog[2], Anolog[3], Anolog[4], Anolog[5], Anolog[6],
          Anolog[7]);
  uart0_send_string((char *)rx_buff);

  delay_ms(100);

  memset(rx_buff, 0, 256);
  // 得到黑白校准值之后，初始化传感器

  No_MCU_Ganv_Sensor_Init(&sensor, white, black);
  //

  delay_ms(100);

  while (1) {

    // 无时基传感器常规任务，包含模拟量，数字量，归一化量
    No_Mcu_Ganv_Sensor_Task_Without_tick(&sensor);
    // 有时基传感器常规任务，包含模拟量，数字量，归一化量
    //			No_Mcu_Ganv_Sensor_Task_With_tick(&sensor)
    // 获取传感器数字量结果(只有当有黑白值传入进去了之后才会有这个值！！)
    Digtal = Get_Digtal_For_User(&sensor);
    sprintf((char *)rx_buff, "Digtal %d-%d-%d-%d-%d-%d-%d-%d\r\n",
            (Digtal >> 0) & 0x01, (Digtal >> 1) & 0x01, (Digtal >> 2) & 0x01,
            (Digtal >> 3) & 0x01, (Digtal >> 4) & 0x01, (Digtal >> 5) & 0x01,
            (Digtal >> 6) & 0x01, (Digtal >> 7) & 0x01);
    uart0_send_string((char *)rx_buff);
    memset(rx_buff, 0, 256);

    // 将各个通道的数字量映射到对应的GPIO输出
    for (int i = 0; i < 8; i++) {
        int channel_level = (Digtal >> i) & 0x01;  // 获取第i个通道的电平状态
        set_output_level(i + 1, channel_level);    // 设置对应GPIO的输出电平
    }

    // 获取传感器模拟量结果(有黑白值初始化后返回1 没有返回 0)
    if (Get_Anolog_Value(&sensor, Anolog)) {
      sprintf((char *)rx_buff, "Anolog %d-%d-%d-%d-%d-%d-%d-%d\r\n", Anolog[0],
              Anolog[1], Anolog[2], Anolog[3], Anolog[4], Anolog[5], Anolog[6],
              Anolog[7]);
      uart0_send_string((char *)rx_buff);
      memset(rx_buff, 0, 256);
    }

    // 获取传感器归一化结果(只有当有黑白值传入进去了之后才会有这个值！！有黑白值初始化后返回1
    // 没有返回 0)
    if (Get_Normalize_For_User(&sensor, Normal)) {
      sprintf((char *)rx_buff, "Normalize %d-%d-%d-%d-%d-%d-%d-%d\r\n",
              Normal[0], Normal[1], Normal[2], Normal[3], Normal[4], Normal[5],
              Normal[6], Normal[7]);
      uart0_send_string((char *)rx_buff);
      memset(rx_buff, 0, 256);
    }
    // 经典版理论性能1khz，只需要delay1ms，青春版100hz，需要delay10ms，否则不能正常使用
    delay_ms(1);
  }
}

void set_output_level(int chanel, int level) {
  if (chanel == 1) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P1_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P1_PIN);
    }
  }
  if (chanel == 2) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P2_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P2_PIN);
    }
  }
  if (chanel == 3) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P3_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P3_PIN);
    }
  }
  if (chanel == 4) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P4_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P4_PIN);
    }
  }
  if (chanel == 5) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P5_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P5_PIN);
    }
  }
  if (chanel == 6) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P6_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P6_PIN);
    }
  }
  if (chanel == 7) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P7_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P7_PIN);
    }
  }
  if (chanel == 8) {
    if (level == 1) {
      DL_GPIO_setPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P8_PIN);
    } else {
      DL_GPIO_clearPins(GPIO_OUTPUT_PORT, GPIO_OUTPUT_P8_PIN);
    }
  }
}
